#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <tchartview.h>
#include <QFileDialog>
#include <QAxObject>
#include <QMessageBox>
#include <QVector>



int start_subject,end_subject; // 学科序号范围
QVector<QVector<int>> scores_range; // 每个分数段学生人数
QStringList categories; // 学科列表
QList<double> average; // 每个学生的平均成绩

void MainWindow::removeAllxis(QChart *chart)
{
    QList<QAbstractAxis *> axisList=chart->axes();
    int count=axisList.count();
    for(int i=0;i<count;i++)
    {
        QAbstractAxis *one=axisList.at(0);
        chart->removeAxis(one);
        axisList.removeFirst();
        delete one;
    }
}

void MainWindow::iniBarChart()
{
    QChart *chart = new QChart();
    chart->setTitle("成绩分析");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->chartViewBar->setChart(chart);
    ui->chartViewBar->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::drawBarChart(bool isVertical)
{
    QChart *chart = ui->chartViewBar->chart();
    chart->setTitle("学生成绩");
    chart->removeAllSeries();
    removeAllxis(chart);

    QLineSeries *seriesLine = new QLineSeries();
    seriesLine->setName("平均分");
    QPen pen(Qt::red);
    pen.setWidth(2);
    seriesLine->setPen(pen);
    QFont font= seriesLine->pointLabelsFont();
    font.setPointSize(12);
    font.setBold(true);
    seriesLine->setPointLabelsFont(font);
    seriesLine->setPointLabelsVisible(true);
    if(isVertical)
        seriesLine->setPointLabelsFormat("@yPoint");
    else
        seriesLine->setPointLabelsFormat("@xPoint");

    QAbstractBarSeries *seriesBar;
    if(isVertical)
        seriesBar= new QBarSeries();
    else
        seriesBar= new QHorizontalBarSeries();
    seriesBar->setLabelsVisible(true);
    seriesBar->setLabelsFormat("@value分");


    for(int it=0;it< categories.count();it++) {
        QBarSet *subject= new QBarSet(categories.at(it));
        for(int i=0;i<dataModel->rowCount();i++)
        {
            int num= dataModel->index(i,it+start_subject).data().toInt();
            subject->append(num);
        }
        seriesBar->append(subject);

    }

    QStringList stu_name; // 每个学生姓名
    for(int i=0;i<dataModel->rowCount();i++)
    {
        if(isVertical)
            seriesLine->append(i,average.at(i));
        else
            seriesLine->append(average.at(i),i);
        stu_name<< dataModel->index(i,start_subject-1).data().toString();
    }

    connect(seriesBar,&QBarSeries::hovered,this,&MainWindow::do_barHovered);
    connect(seriesBar,&QBarSeries::clicked,this,&MainWindow::do_barClicked);
    chart->addSeries(seriesBar);
    chart->addSeries(seriesLine);


    QBarCategoryAxis *axisStud = new QBarCategoryAxis();
    axisStud->append(stu_name); //为棒柱添加学生姓名
    axisStud->setRange(stu_name.at(0),stu_name.at(stu_name.count()-1));

    QValueAxis *axisValue = new QValueAxis();
    axisValue->setRange(0,100);
    axisValue->setTitleText("分数");
    axisValue->setTickCount(10);
    axisValue->setLabelFormat("%.0f");
    axisValue->applyNiceNumbers();

    if(isVertical)
    {
        chart->addAxis(axisStud,Qt::AlignBottom);
        chart->addAxis(axisValue,Qt::AlignLeft);
    }
    else
    {
        chart->addAxis(axisStud,Qt::AlignLeft);
        chart->addAxis(axisValue,Qt::AlignBottom);
    }
    seriesBar->attachAxis(axisStud);
    seriesBar->attachAxis(axisValue);
    seriesLine->attachAxis(axisStud);
    seriesLine->attachAxis(axisValue);
    chart->legend()->setAlignment(Qt::AlignBottom);
}

void MainWindow::iniStackedBar()
{
    QChart *chart = new QChart();
    chart->setTitle("StackedBar 演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->chartViewStackedBar->setChart(chart);
    ui->chartViewStackedBar->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::drawStackedBar(bool isVertical)
{
    QChart *chart = ui->chartViewStackedBar->chart();
    if(isVertical)
        chart->setTitle("StackedBar 演示");
    else
        chart->setTitle("Horizontal StackedBar 演示");
    chart->removeAllSeries();
    removeAllxis(chart);

    QAbstractBarSeries *seriesBar;
    if(isVertical)
        seriesBar= new QStackedBarSeries();
    else
        seriesBar= new QHorizontalStackedBarSeries();
    seriesBar->setLabelsVisible(true);

    for(int it=0;it< categories.count();it++) {
        QBarSet *subject= new QBarSet(categories.at(it));
        for(int i=0;i<dataModel->rowCount();i++)
        {
            int num= dataModel->index(i,it+start_subject).data().toInt();
            subject->append(num);
        }
        seriesBar->append(subject);

    }

    QStringList stu_name;
    for(int i=0;i<dataModel->rowCount();i++)
    {
//        if(isVertical)
//            seriesLine->append(i,average.at(i));
//        else
//            seriesLine->append(average.at(i),i);
        stu_name<< dataModel->index(i,start_subject-1).data().toString();
    }



    QBarCategoryAxis *axisStud = new QBarCategoryAxis();
    axisStud->append(stu_name);
    axisStud->setRange(stu_name.at(0),stu_name.at(stu_name.count()-1));

    //seriesBar->append(barSetList);
    connect(seriesBar,&QBarSeries::hovered,this,&MainWindow::do_barHovered);
    connect(seriesBar,&QBarSeries::clicked,this,&MainWindow::do_barClicked);
    chart->addSeries(seriesBar);

    QValueAxis *axisValue = new QValueAxis();
    int range= (end_subject-start_subject)*100;
    axisValue->setRange(0,range);
    axisValue->setTitleText("总分");
    axisValue->setTickCount(7);
    axisValue->setLabelFormat("%.0f");
    axisValue->applyNiceNumbers();

    if(isVertical)
    {
        chart->addAxis(axisStud,Qt::AlignBottom);
        chart->addAxis(axisValue,Qt::AlignLeft);
    }
    else
    {
        chart->addAxis(axisStud,Qt::AlignLeft);
        chart->addAxis(axisValue,Qt::AlignBottom);
    }
    seriesBar->attachAxis(axisStud);
    seriesBar->attachAxis(axisValue);

    chart->legend()->setAlignment(Qt::AlignRight);
}

void MainWindow::iniPercentBar()
{
    QChart *chart = new QChart();
    chart->setTitle("PercentBar 演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->chartViewPercentBar->setChart(chart);
    ui->chartViewPercentBar->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::drawPercentBar(bool isVertical)
{
    QChart *chart = ui->chartViewPercentBar->chart();
    if(isVertical)
        chart->setTitle("PercentBar 演示");
    else
        chart->setTitle("Horizontal PercentBar 演示");
    chart->removeAllSeries();
    removeAllxis(chart);


    QList<QBarSet*> barSetList;
    QStringList list;
    list << "60分以下" << "60-69分" << "70-7分9" << "80-89分" << "90分及以上" ;
    for(int i=0;i<5;i++)
    {

        QBarSet *barSet = new QBarSet(list.at(i));
        barSetList.append(barSet);
        for (auto it:scores_range[i]) {
            barSet->append(it);
        }
    }


    QAbstractBarSeries *seriesBar;
    if(isVertical)
        seriesBar= new QPercentBarSeries();
    else
        seriesBar= new QHorizontalPercentBarSeries();
    seriesBar->setLabelsVisible(true);
    //    seriesBar->setLabelsFormat("@value分");
    seriesBar->append(barSetList);
    connect(seriesBar,&QBarSeries::hovered,this,&MainWindow::do_barHovered);
    connect(seriesBar,&QBarSeries::clicked,this,&MainWindow::do_barClicked);
    chart->addSeries(seriesBar);

    QBarCategoryAxis *axisSection = new QBarCategoryAxis();

    axisSection->append(categories);
    axisSection->setRange(categories.at(0),categories.at(categories.count()-1));

    QValueAxis *axisValue = new QValueAxis();
    axisValue->setRange(0,100);
    axisValue->setTitleText("积累百分比");
    axisValue->setTickCount(6);
    axisValue->setLabelFormat("%.0f%%");
    //axisValue->applyNiceNumbers();

    if(isVertical)
    {
        chart->addAxis(axisSection,Qt::AlignBottom);
        chart->addAxis(axisValue,Qt::AlignLeft);
    }
    else
    {
        chart->addAxis(axisSection,Qt::AlignLeft);
        chart->addAxis(axisValue,Qt::AlignBottom);
    }
    seriesBar->attachAxis(axisSection);
    seriesBar->attachAxis(axisValue);

    chart->legend()->setAlignment(Qt::AlignRight);
}

void MainWindow::iniPieChart()
{
    QChart *chart = new QChart();
    chart->setTitle("PieChart 演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->chartViewPie->setChart(chart);
    ui->chartViewPie->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::drawPieChart()
{
    QChart *chart= ui->chartViewPie->chart();
    chart->removeAllSeries();

    int colNo= ui->comboBox_3->currentIndex();
    QPieSeries *seriesPie = new QPieSeries();
    seriesPie->setHoleSize(ui->doubleSpinBox_2->value());
    QStringList list;
    list << "60分以下" << "60-69分" << "70-79分" << "80-89分" << "90分及以上" ;
    for(int i=0;i<=4;i++)
    {
        seriesPie->append(list.at(i),scores_range[i][colNo]);
    }

    QPieSlice *slice;
    for(int i=0;i<=4;i++)
    {
        slice= seriesPie->slices().at(i);
        slice->setLabel(slice->label() + QString::asprintf(": %.0f人,%.1f%%",
                                   slice->value(),slice->percentage()*100));
    }
    slice->setExploded(true);
    chart->setAcceptHoverEvents(true);
    connect(seriesPie,&QPieSeries::hovered,this,&MainWindow::do_pieHovered);

    seriesPie->setLabelsVisible(true);
    chart->addSeries(seriesPie);
    chart->setTitle("Piechart----"+ui->comboBox_3->currentText());
    chart->legend()->setAlignment(Qt::AlignRight);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->tableView->setAlternatingRowColors(true);
    dataModel= new QStandardItemModel(this);
    connect(dataModel,&QStandardItemModel::itemChanged,
            this,&MainWindow::do_calcuAverage);





//   iniBarChart();
//   iniStackedBar();
//    iniPercentBar();
//    iniPieChart();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::do_calcuAverage(QStandardItem *item)
{
//    if(item->column()<COL_MATH || item->column()>COL_ENGLISH)
//        return;
//    int rowNo= item->row();
//    qreal avg= 0;
//    QStandardItem *aItem;
//    for(int i=COL_MATH;i<COL_ENGLISH;i++)
//    {
//        aItem= dataModel->item(rowNo,i);
//        avg += aItem->text().toDouble();
//    }
//    avg= avg/3;
//    aItem= dataModel->item(rowNo,COL_AVERAGE);
//    aItem->setText(QString::asprintf("%.1f",avg));
    return;
}

void MainWindow::do_barHovered(bool status, int index, QBarSet *barset)
{
    QString str= "hovered barSet=" + barset->label();
    if(status)
        str += QString::asprintf(",index=%d,value=%.2f",index,barset->at(index));
    else
        str="";
    ui->statusbar->showMessage(str);
}

void MainWindow::do_barClicked(int index, QBarSet *barset)
{
    QString str= "clicked barSet=" + barset->label();
    str += QString::asprintf(",index=%d,count=%d",index,barset->count());
    ui->statusbar->showMessage(str);
}

void MainWindow::do_pieHovered(QPieSlice *slice, bool state)
{
    slice->setExploded(state);
}


void MainWindow::on_pushButton_4_clicked()
{
    drawBarChart(true);
}


void MainWindow::on_pushButton_5_clicked()
{
    drawBarChart(false);
}


void MainWindow::on_pushButton_clicked()
{
    dataModel= new QStandardItemModel(this);
    QString curPath= QDir::currentPath();
    QString dlgTitle= "打开一个文件";
    QString filter= "excel文件(*.xlsx);;文本文件(*.txt);;所有文件(*.*)";
    QString excel_file= QFileDialog::getOpenFileName(this,dlgTitle,curPath,filter);
    readExcelUsedRange(excel_file);
}


void MainWindow::on_pushButton_8_clicked()
{
    drawStackedBar(true);
}


void MainWindow::on_pushButton_9_clicked()
{
    drawStackedBar(false);
}


void MainWindow::on_pushButton_10_clicked()
{
    drawPercentBar(true);
}


void MainWindow::on_pushButton_11_clicked()
{
    drawPercentBar(false);
}


void MainWindow::on_comboBox_3_currentIndexChanged(int index)
{
    Q_UNUSED(index);
    //drawPieChart();
}


void MainWindow::on_pushButton_12_clicked()
{
    drawPieChart();
}








void MainWindow::on_doubleSpinBox_valueChanged(double arg1)
{
    QPieSeries *series;
    series= static_cast<QPieSeries*>(ui->chartViewPie->chart()->series().at(0));
    series->setHoleSize(arg1);
}


void MainWindow::on_checkBox_clicked(bool checked)
{
    ui->chartViewPie->chart()->legend()->setVisible(checked);
}

void MainWindow::readExcelUsedRange(QString fileName) {
    // 创建 Excel 应用程序对象
    QAxObject *excel = new QAxObject("Excel.Application");
    excel->dynamicCall("SetVisible(bool)", false); // 设置 Excel 应用程序为不可见
    // 打开工作簿
    QAxObject *workbooks = excel->querySubObject("Workbooks");
    QAxObject *workbook = workbooks->querySubObject("Open(QString)", fileName);
    // 选择第一个工作表
    QAxObject *sheet = workbook->querySubObject("Worksheets(int)", 1);
    // 获取已使用范围
    QAxObject *usedRange = sheet->querySubObject("UsedRange");

    QVariant var;
    dataModel->clear();
    if(NULL == usedRange || usedRange->isNull())
    {
        QMessageBox::critical(this,"错误！","Excel表无内容");
        return ;
    }
    var = usedRange->dynamicCall("Value"); // 将Excel表传入QVariant数据中
    delete usedRange;
    // 关闭工作簿和 Excel 应用程序
    workbook->dynamicCall("Close()");
    excel->dynamicCall("Quit()");
    delete excel;


    QVariantList varRows = var.toList(); // 将QVariant数据转化为QVariantList，等同于QList<QVariant>

    int rowCount = varRows.count(); // 总行数
    QStringList headerList;
    QVariantList rowData;
    rowData = varRows[0].toList();
    int count= rowData.count(); // 第一行列数
    for (int i = 0; i < count; ++i) {
        QString str= rowData[i].toString();
        headerList << str;
        if(str.contains("姓名") )
            start_subject= i+1; // 第一个学科序号
        if(str.contains("总分") )
            end_subject= i; // 最后一个学科序号+1
    }
    dataModel->setHorizontalHeaderLabels(headerList); // 表头

    QList<QStandardItem*> itemList;
    QStandardItem *item;
    for(int i=1;i<rowCount;i++)
    {
        itemList.clear();
        rowData = varRows[i].toList();
        for (int j = 0; j < count; ++j) {
            item= new QStandardItem(rowData[j].toString());
            item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
            itemList<<item;
        }
        dataModel->appendRow(itemList);
    }
    ui->tableView->setModel(dataModel);

    for (int j = start_subject; j < end_subject; ++j) {
        QString subject= dataModel->headerData(j,Qt::Horizontal,Qt::DisplayRole).toString();
        categories<< subject;
    }



    // 载入图表需要的数据
    int range= end_subject - start_subject;

    QVector<int> scores_list;
    for (int i = 0; i < range; ++i) {
        scores_list.push_back(0); // 初始化一行分数段人数为0
    }
    for (int i = 0; i < 5; ++i) {
        scores_range.push_back(scores_list); // 将五行为0的分数段人数推入二维容器中
    }

    // 统计每个分数段人数并且载入全局变量中
    for (int i = 0; i < dataModel->rowCount(); ++i) {
        int gross_score=0;
        for (int j = start_subject; j < end_subject; ++j) {
            int score= dataModel->index(i,j).data().toInt();
            gross_score+=score;
            if(score<60 && score>=0)
                scores_range[0][j-start_subject]+= 1;
            else if(score>=60 && score<70)
                scores_range[1][j-start_subject]+= 1;
            else if(score>=70 && score<80)
                scores_range[2][j-start_subject]+= 1;
            else if(score>=80 && score<90)
                scores_range[3][j-start_subject]+= 1;
            else
                scores_range[4][j-start_subject]+= 1;
        }
        average<< gross_score/range; // 将一个学生的平均分写入全局变量average中
    }

    ui->comboBox_3->addItems(categories);

}


void MainWindow::on_doubleSpinBox_2_valueChanged(double arg1)
{
    QPieSeries *series;
    series= static_cast<QPieSeries*>(ui->chartViewPie->chart()->series().at(0));
    series->setHoleSize(arg1);
}

